package ch01.GridCollision {
	/**
	 * 网格检测例子三，使得小球移动起来
	 * @author jianping.shenjp
	 */
	import flash.display.Sprite;
	import flash.display.StageAlign;
	import flash.display.StageScaleMode;
	import flash.display.DisplayObject;
	import flash.events.Event;
    import flash.utils.getTimer;
	import tools.Ball;

	public class GridCollision3 extends Sprite {
		private const GRID_SIZE:Number = 80;
		private const RADIUS:Number = 25;
		private var _balls:Vector.<DisplayObject>;
		private var _grid:CollisionGrid;
		private var _numBalls:int = 400;
		private var _numChecks:int = 0;

		public function GridCollision3(){
			stage.align = StageAlign.TOP_LEFT;
			stage.scaleMode = StageScaleMode.NO_SCALE;
			_grid = new CollisionGrid(stage.stageWidth, stage.stageHeight, GRID_SIZE);
			_grid.drawGrid(graphics);
			makeBalls();
			addEventListener(Event.ENTER_FRAME, onEnterFrame);
		}

		private function onEnterFrame(event:Event):void {
			_numChecks = 0;
			var startTime:int;
			var elapsed:int;
			startTime = getTimer();
			updateBalls();
			_grid.check(_balls);
			var checks:Vector.<DisplayObject> = _grid.checks;
			var numChecks:int = checks.length - 1;
			for (var j:int = 0; j < numChecks; j += 2){
				checkCollision(checks[j] as Ball, checks[j + 1] as Ball);
			}
			elapsed = getTimer() - startTime;
			//这儿测试的结果，速度比起之前的几乎快了一倍。这得归功于使用了vector 以及仅创建需要的网格（懒惰实例化）。
			trace("3:Elapsed:", elapsed, "测试次数:", _numChecks);
		}

		private function makeBalls():void {
			_balls = new Vector.<DisplayObject>(_numBalls);
			for (var i:int = 0; i < _numBalls; i++){
				var ball:Ball = new Ball(RADIUS);
				ball.x = Math.random() * stage.stageWidth;
				ball.y = Math.random() * stage.stageHeight;
				ball.vx = Math.random() * 4 - 2;
				ball.vy = Math.random() * 4 - 2;
				addChild(ball);
				_balls[i] = ball;
			}
		}

		private function updateBalls():void {
			for (var i:int = 0; i < _numBalls; i++){
				var ball:Ball = _balls[i] as Ball;
				ball.update();
				if (ball.x < RADIUS){
					ball.x = RADIUS;
					ball.vx *= -1;
				} else if (ball.x > stage.stageWidth - RADIUS){
					ball.x = stage.stageWidth - RADIUS;
					ball.vx *= -1;
				}
				if (ball.y < RADIUS){
					ball.y = RADIUS;
					ball.vy *= -1;
				} else if (ball.y > stage.stageHeight - RADIUS){
					ball.y = stage.stageHeight - RADIUS;
					ball.vy *= -1;
				}
				ball.color = 0xFFFFFF;
			}
		}

		private function checkCollision(ballA:Ball, ballB:Ball):void {
			_numChecks++;
			var dx:Number = ballB.x - ballA.x;
			var dy:Number = ballB.y - ballA.y;
			var dist:Number = Math.sqrt(dx * dx + dy * dy);
			if (dist < ballA.radius + ballB.radius){
				ballA.color = 0xFF0000;
				ballB.color = 0xFF0000;
			}
		}
	}

}